﻿// Copyright (c) 2012 - 2020 Jared Zheng <jaredz at outlook dot com>
// Buddha Framework is licensed under Mulan PSL v2.
// You can use this software according to the terms and conditions of the Mulan PSL v2.
// You may obtain a copy of Mulan PSL v2 at:
//          http://license.coscl.org.cn/MulanPSL2
// THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
// EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
// MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
// See the Mulan PSL v2 for more details.
//
// Create : 2012-12-01 version 0.1 Jared Zheng <jaredz at outlook dot com>
// Update : 2018-12-05 version 3.1.5 Jared Zheng <jaredz at outlook dot com>

#include "stdafx.h"
#include "exception.h"
#include "MainFrame.h"

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// CServerLoader

IMPLEMENT_CLASS_LOADER( CServerLoader, XUI )
IMPLEMENT_CLASS_LOADER( CServerLoader, NET )
IMPLEMENT_CLASS_LOADER( CServerLoader, Center )
IMPLEMENT_CLASS_LOADER( CServerLoader, Balance )
IMPLEMENT_CLASS_LOADER( CServerLoader, AuthorDB )
IMPLEMENT_CLASS_LOADER( CServerLoader, Author )
IMPLEMENT_CLASS_LOADER( CServerLoader, MasterDB )
IMPLEMENT_CLASS_LOADER( CServerLoader, Master )
IMPLEMENT_CLASS_LOADER( CServerLoader, Service )
IMPLEMENT_CLASS_LOADER( CServerLoader, Gate )

#if (__PLATFORM_TARGET__ == PLATFORM_TARGET_WINDOWS)
Int CServerLoader::ThreadExceptHandler(TId tThreadId, Int nThreadType, Int nThreadRoutine, void*, struct _EXCEPTION_POINTERS* pExceptInfo)
{
    CString strName = TF("ThreadExceptHandler");
    strName.AppendFormat(TF("[%d-%d-%d]"), tThreadId, nThreadType, nThreadRoutine);
    CSEHException::Dump(pExceptInfo, *strName);
    return EXCEPTION_CONTINUE_SEARCH;
}
#endif

CServerLoader::CServerLoader(void)
{
}

CServerLoader::~CServerLoader(void)
{
}

bool CServerLoader::Init(PCXStr pszCmd)
{
    if (pszCmd != nullptr)
    {
        m_Config.SetArgs(pszCmd);
    }
    if (m_Config.Init())
    {
        return InitSystems();
    }
    return false;
}

bool CServerLoader::Init(Int nArgc, PXStr* ppszArgv)
{
    if (nArgc > 1)
    {
        m_Config.SetArgs(nArgc, ppszArgv);
    }
    if (m_Config.Init())
    {
        return InitSystems();
    }
    return false;
}

void CServerLoader::Exit(void)
{
    StopServers();
    UnloadServers();

    ExitSystems();
    m_Config.Exit();
}

bool CServerLoader::LoadServer(Int nServer, CEventHandler* pSHandler)
{
    if (m_Config.GetLoadServers() & nServer)
    {
        assert(pSHandler != nullptr);
        CStringFix strPath;
        if (m_Config.GetServerPath(nServer, strPath) == false)
        {
            DEV_ERROR(TF("服务器类型%X在配置文件中不存在文件路径"), nServer);
            IXWnd::MessageBoxParam(TF("服务器类型%X在配置文件中不存在文件路径"), TF("ServerLoader"), MB_OK, nullptr, nServer);
            return false;
        }
        switch (nServer)
        {
        case CServerConfig::CFG_LOAD_CENTER:
            {
                if (m_CenterServer != nullptr)
                {
                    DEV_ERROR(TF("加载同步管理服务器模块失败, 同步管理服务器模块已经存在"));
                    IXWnd::MessageBoxParam(TF("加载同步管理服务器模块失败, 同步管理服务器模块已经存在"), TF("ServerLoader"));
                    return false;
                }
                INIT_CLASS_LOADER( CServerLoader, Center, UUID_OF(CCommonServerSystem), *strPath );
                LOADER_CLASS_CREEATE( CServerLoader, Center, UUID_OF(ICenterServer), m_CenterServer.Cast<CComponent>() );
                if ((m_CenterServer == nullptr) || (m_CenterServer->Init(*pSHandler, m_Config) != RET_OKAY))
                {
                    DEV_ERROR(TF("加载同步管理服务器模块失败"));
                    IXWnd::MessageBoxParam(TF("加载同步管理服务器模块失败"), TF("ServerLoader"));
                    return false;
                }
                DEV_INFO(TF("加载同步管理服务器模块完成"));
                pSHandler->OnHandle(PAKT_CENTER, reinterpret_cast<uintptr_t>(m_CenterServer.Get()), 0);
            }
            break;
        case CServerConfig::CFG_LOAD_BALANCE:
            {
                if (m_BalanceServer != nullptr)
                {
                    DEV_ERROR(TF("加载授权均衡服务器模块失败, 授权均衡服务器模块已经存在"));
                    IXWnd::MessageBoxParam(TF("加载授权均衡服务器模块失败, 授权均衡服务器模块已经存在"), TF("ServerLoader"));
                    return false;
                }
                INIT_CLASS_LOADER( CServerLoader, Balance, UUID_OF(CCommonServerSystem), *strPath );
                LOADER_CLASS_CREEATE( CServerLoader, Balance, UUID_OF(IBalanceServer), m_BalanceServer.Cast<CComponent>() );
                if ((m_BalanceServer == nullptr) || (m_BalanceServer->Init(*pSHandler, m_Config) != RET_OKAY))
                {
                    DEV_ERROR(TF("加载授权均衡服务器模块失败"));
                    IXWnd::MessageBoxParam(TF("加载授权均衡服务器模块失败"), TF("ServerLoader"));
                    return false;
                }
                DEV_INFO(TF("加载授权均衡服务器模块完成"));
                pSHandler->OnHandle(PAKT_BALANCE, reinterpret_cast<uintptr_t>(m_BalanceServer.Get()), 0);
            }
            break;
        case CServerConfig::CFG_LOAD_AUTHORDB:
            {
                if (m_AuthorDBServer != nullptr)
                {
                    DEV_ERROR(TF("加载授权数据服务器模块失败, 授权数据服务器模块已经存在"));
                    IXWnd::MessageBoxParam(TF("加载授权数据服务器模块失败, 授权数据服务器模块已经存在"), TF("ServerLoader"));
                    return false;
                }
                INIT_CLASS_LOADER( CServerLoader, AuthorDB, UUID_OF(CCommonServerSystem), *strPath );
                LOADER_CLASS_CREEATE( CServerLoader, AuthorDB, UUID_OF(IAuthorDBServer), m_AuthorDBServer.Cast<CComponent>() );
                if ((m_AuthorDBServer == nullptr) || (m_AuthorDBServer->Init(*pSHandler, m_Config) != RET_OKAY))
                {
                    DEV_ERROR(TF("加载授权数据服务器模块失败"));
                    IXWnd::MessageBoxParam(TF("加载授权数据服务器模块失败"), TF("ServerLoader"));
                    return false;
                }
                DEV_INFO(TF("加载授权数据服务器模块完成"));
                pSHandler->OnHandle(PAKT_AUTHORDB, reinterpret_cast<uintptr_t>(m_AuthorDBServer.Get()), 0);
            }
            break;
        case CServerConfig::CFG_LOAD_AUTHOR:
            {
                if (m_AuthorServer != nullptr)
                {
                    DEV_ERROR(TF("加载授权网关服务器模块失败, 授权网关服务器模块已经存在"));
                    IXWnd::MessageBoxParam(TF("加载授权网关服务器模块失败, 授权网关服务器模块已经存在"), TF("ServerLoader"));
                    return false;
                }
                INIT_CLASS_LOADER( CServerLoader, Author, UUID_OF(CCommonServerSystem), *strPath );
                LOADER_CLASS_CREEATE( CServerLoader, Author, UUID_OF(IAuthorServer), m_AuthorServer.Cast<CComponent>() );
                if ((m_AuthorServer == nullptr) || (m_AuthorServer->Init(*pSHandler, m_Config) != RET_OKAY))
                {
                    DEV_ERROR(TF("加载授权网关服务器模块失败"));
                    IXWnd::MessageBoxParam(TF("加载授权网关服务器模块失败"), TF("ServerLoader"));
                    return false;
                }
                DEV_INFO(TF("加载授权网关服务器模块完成"));
                pSHandler->OnHandle(PAKT_AUTHOR, reinterpret_cast<uintptr_t>(m_AuthorServer.Get()), 0);
            }
            break;
        case CServerConfig::CFG_LOAD_MASTERDB:
            {
                if (m_MasterDBServer != nullptr)
                {
                    DEV_ERROR(TF("加载业务数据服务器模块失败, 业务数据服务器模块已经存在"));
                    IXWnd::MessageBoxParam(TF("加载业务数据服务器模块失败, 业务数据服务器模块已经存在"), TF("ServerLoader"));
                    return false;
                }
                INIT_CLASS_LOADER( CServerLoader, MasterDB, UUID_OF(CCommonServerSystem), *strPath );
                LOADER_CLASS_CREEATE( CServerLoader, MasterDB, UUID_OF(IMasterDBServer), m_MasterDBServer.Cast<CComponent>() );
                if ((m_MasterDBServer == nullptr) || (m_MasterDBServer->Init(*pSHandler, m_Config) != RET_OKAY))
                {
                    DEV_ERROR(TF("加载业务数据服务器模块失败"));
                    IXWnd::MessageBoxParam(TF("加载业务数据服务器模块失败"), TF("ServerLoader"));
                    return false;
                }
                DEV_INFO(TF("加载业务数据服务器模块完成"));
                pSHandler->OnHandle(PAKT_MASTERDB, reinterpret_cast<uintptr_t>(m_MasterDBServer.Get()), 0);
            }
            break;
        case CServerConfig::CFG_LOAD_MASTER:
            {
                if (m_MasterServer != nullptr)
                {
                    DEV_ERROR(TF("加载业务管理服务器模块失败, 业务管理服务器模块已经存在"));
                    IXWnd::MessageBoxParam(TF("加载业务管理服务器模块失败, 业务管理服务器模块已经存在"), TF("ServerLoader"));
                    return false;
                }
                INIT_CLASS_LOADER( CServerLoader, Master, UUID_OF(CCommonServerSystem), *strPath );
                LOADER_CLASS_CREEATE( CServerLoader, Master, UUID_OF(IMasterServer), m_MasterServer.Cast<CComponent>() );
                if ((m_MasterServer == nullptr) || (m_MasterServer->Init(*pSHandler, m_Config) != RET_OKAY))
                {
                    DEV_ERROR(TF("加载业务管理服务器模块失败"));
                    IXWnd::MessageBoxParam(TF("加载业务管理服务器模块失败"), TF("ServerLoader"));
                    return false;
                }
                DEV_INFO(TF("加载业务管理服务器模块完成"));
                pSHandler->OnHandle(PAKT_MASTER, reinterpret_cast<uintptr_t>(m_MasterServer.Get()), 0);
            }
            break;
        case CServerConfig::CFG_LOAD_SERVICE:
            {
                if (m_ServiceServer != nullptr)
                {
                    DEV_ERROR(TF("加载业务功能服务器模块失败, 业务功能服务器模块已经存在"));
                    IXWnd::MessageBoxParam(TF("加载业务功能服务器模块失败, 业务功能服务器模块已经存在"), TF("ServerLoader"));
                    return false;
                }
                INIT_CLASS_LOADER( CServerLoader, Service, UUID_OF(CCommonServerSystem), *strPath );
                LOADER_CLASS_CREEATE( CServerLoader, Service, UUID_OF(IServiceServer), m_ServiceServer.Cast<CComponent>() );
                if ((m_ServiceServer == nullptr) || (m_ServiceServer->Init(*pSHandler, m_Config) != RET_OKAY))
                {
                    DEV_ERROR(TF("加载业务功能服务器模块失败"));
                    IXWnd::MessageBoxParam(TF("加载业务功能服务器模块失败"), TF("ServerLoader"));
                    return false;
                }
                DEV_INFO(TF("加载业务功能服务器模块完成"));
                pSHandler->OnHandle(PAKT_SERVICE, reinterpret_cast<uintptr_t>(m_ServiceServer.Get()), 0);
            }
            break;
        case CServerConfig::CFG_LOAD_GATE:
            {
                if (m_GateServer != nullptr)
                {
                    DEV_ERROR(TF("加载业务网关服务器模块失败, 业务网关服务器模块已经存在"));
                    IXWnd::MessageBoxParam(TF("加载业务网关服务器模块失败, 业务网关服务器模块已经存在"), TF("ServerLoader"));
                    return false;
                }
                INIT_CLASS_LOADER( CServerLoader, Gate, UUID_OF(CCommonServerSystem), *strPath );
                LOADER_CLASS_CREEATE( CServerLoader, Gate, UUID_OF(IGateServer), m_GateServer.Cast<CComponent>() );
                if ((m_GateServer == nullptr) || (m_GateServer->Init(*pSHandler, m_Config) != RET_OKAY))
                {
                    DEV_ERROR(TF("加载业务网关服务器模块失败"));
                    IXWnd::MessageBoxParam(TF("加载业务网关服务器模块失败"), TF("ServerLoader"));
                    return false;
                }
                DEV_INFO(TF("加载业务网关服务器模块完成"));
                pSHandler->OnHandle(PAKT_GATE, reinterpret_cast<uintptr_t>(m_GateServer.Get()), 0);
            }
            break;
        default:
            {
                DEV_WARN(TF("未知的服务器类型%X"), nServer);
                IXWnd::MessageBoxParam(TF("未知的服务器类型%X"), TF("ServerLoader"), MB_OK, nullptr, nServer);
                return false;
            }
        }
        return true;
    }
    else
    {
        DEV_WARN(TF("服务器类型%X在配置文件中不存在加载配置"), nServer);
        IXWnd::MessageBoxParam(TF("服务器类型%X在配置文件中不存在加载配置"), TF("ServerLoader"), MB_OK, nullptr, nServer);
    }
    return false;
}

void CServerLoader::UnloadServers(void)
{
    if (m_GateServer != nullptr)
    {
        m_GateServer->Exit();
        m_GateServer = nullptr;
        DEV_INFO(TF("卸载业务网关服务器模块完成"));
    }
    if (m_ServiceServer != nullptr)
    {
        m_ServiceServer->Exit();
        m_ServiceServer = nullptr;
        DEV_INFO(TF("卸载业务功能服务器模块完成"));
    }
    if (m_MasterServer != nullptr)
    {
        m_MasterServer->Exit();
        m_MasterServer = nullptr;
        DEV_INFO(TF("卸载业务管理服务器模块完成"));
    }
    if (m_MasterDBServer != nullptr)
    {
        m_MasterDBServer->Exit();
        m_MasterDBServer = nullptr;
        DEV_INFO(TF("卸载业务数据服务器模块完成"));
    }
    if (m_AuthorServer != nullptr)
    {
        m_AuthorServer->Exit();
        m_AuthorServer = nullptr;
        DEV_INFO(TF("卸载授权网关服务器模块完成"));
    }
    if (m_AuthorDBServer != nullptr)
    {
        m_AuthorDBServer->Exit();
        m_AuthorDBServer = nullptr;
        DEV_INFO(TF("卸载授权数据服务器模块完成"));
    }
    if (m_BalanceServer != nullptr)
    {
        m_BalanceServer->Exit();
        m_BalanceServer = nullptr;
        DEV_INFO(TF("卸载授权均衡服务器模块完成"));
    }
    if (m_CenterServer != nullptr)
    {
        m_CenterServer->Exit();
        m_CenterServer = nullptr;
        DEV_INFO(TF("卸载同步管理服务器模块完成"));
    }
    EXIT_CLASS_LOADER( CServerLoader, Center );
    EXIT_CLASS_LOADER( CServerLoader, Balance );
    EXIT_CLASS_LOADER( CServerLoader, AuthorDB );
    EXIT_CLASS_LOADER( CServerLoader, Author );
    EXIT_CLASS_LOADER( CServerLoader, MasterDB );
    EXIT_CLASS_LOADER( CServerLoader, Master );
    EXIT_CLASS_LOADER( CServerLoader, Service );
    EXIT_CLASS_LOADER( CServerLoader, Gate );
}

bool CServerLoader::StartServers(void)
{
    if (m_NetworkPtr != nullptr)
    {
        CNETTraits::NET_ATTR attr;
        attr.nAttrs     = m_Config.GetNetworkAttr();
        attr.nThread    = m_Config.GetNetworkThread();
        attr.nAckTime   = m_Config.GetNetworkAck();
        attr.nTimeout   = m_Config.GetNetworkTimeout();
        attr.nMaxBuffer = m_Config.GetNetworkBuffer();
        attr.nMaxJumbo  = m_Config.GetNetworkJumbo();
        if (attr.nAttrs & CNETTraits::ATTR_NAGLE)
        {
            attr.nAttrs &= (~CNETTraits::ATTR_NAGLE); // 去掉ATTR_NAGLE, 保持心态包的即使收发
        }
#ifdef __USE_DEFAULT_NET_BUILD__
        if (m_NetworkPtr->Init(attr) != RET_OKAY)
        {
#else
        if (m_NetworkPtr->Init(attr, nullptr, MNEW CFrameworkNETPackBuild) != RET_OKAY)
        {
#endif
            DEV_ERROR(TF("初始化网络模块失败!"));
            IXWnd::MessageBoxParam(TF("初始化网络模块失败!"), TF("ServerLoader"));
            return false;
        }
    }
    else
    {
        DEV_ERROR(TF("加载网络模块失败!"));
        IXWnd::MessageBoxParam(TF("加载网络模块失败!"), TF("ServerLoader"));
        return false;
    }

    if (m_CenterServer != nullptr)
    {
        if (m_CenterServer->Start() == false)
        {
            DEV_ERROR(TF("启动同步管理服务器服务器失败!"));
            IXWnd::MessageBoxParam(TF("启动同步管理服务器服务器失败!"), TF("ServerLoader"));
            return false;
        }
    }
    if (m_BalanceServer != nullptr)
    {
        if (m_BalanceServer->Start() == false)
        {
            DEV_ERROR(TF("启动授权均衡服务器服务器失败!"));
            IXWnd::MessageBoxParam(TF("启动授权均衡服务器服务器失败!"), TF("ServerLoader"));
            return false;
        }
    }
    if (m_AuthorDBServer != nullptr)
    {
        if (m_AuthorDBServer->Start() == false)
        {
            DEV_ERROR(TF("启动授权数据服务器服务器失败!"));
            IXWnd::MessageBoxParam(TF("启动授权数据服务器服务器失败!"), TF("ServerLoader"));
            return false;
        }
    }
    if (m_AuthorServer != nullptr)
    {
        if (m_AuthorServer->Start() == false)
        {
            DEV_ERROR(TF("启动授权网关服务器服务器失败!"));
            IXWnd::MessageBoxParam(TF("启动授权网关服务器服务器失败!"), TF("ServerLoader"));
            return false;
        }
    }
    if (m_MasterDBServer != nullptr)
    {
        if (m_MasterDBServer->Start() == false)
        {
            DEV_ERROR(TF("启动业务数据服务器服务器失败!"));
            IXWnd::MessageBoxParam(TF("启动业务数据服务器服务器失败!"), TF("ServerLoader"));
            return false;
        }
    }
    if (m_MasterServer != nullptr)
    {
        if (m_MasterServer->Start() == false)
        {
            DEV_ERROR(TF("启动业务管理服务器服务器失败!"));
            IXWnd::MessageBoxParam(TF("启动业务管理服务器服务器失败!"), TF("ServerLoader"));
            return false;
        }
    }
    if (m_ServiceServer != nullptr)
    {
        if (m_ServiceServer->Start() == false)
        {
            DEV_ERROR(TF("启动业务功能服务器服务器失败!"));
            IXWnd::MessageBoxParam(TF("启动业务功能服务器服务器失败!"), TF("ServerLoader"));
            return false;
        }
    }
    if (m_GateServer != nullptr)
    {
        if (m_GateServer->Start() == false)
        {
            DEV_ERROR(TF("启动业务网关服务器服务器失败!"));
            IXWnd::MessageBoxParam(TF("启动业务网关服务器服务器失败!"), TF("ServerLoader"));
            return false;
        }
    }
    return true;
}

void CServerLoader::StopServers(void)
{
    if (m_GateServer != nullptr)
    {
        m_GateServer->Stop();
    }
    if (m_ServiceServer != nullptr)
    {
        m_ServiceServer->Stop();
    }
    if (m_MasterServer != nullptr)
    {
        m_MasterServer->Stop();
    }
    if (m_MasterDBServer != nullptr)
    {
        m_MasterDBServer->Stop();
    }
    if (m_AuthorServer != nullptr)
    {
        m_AuthorServer->Stop();
    }
    if (m_AuthorDBServer != nullptr)
    {
        m_AuthorDBServer->Stop();
    }
    if (m_BalanceServer != nullptr)
    {
        m_BalanceServer->Stop();
    }
    if (m_CenterServer != nullptr)
    {
        m_CenterServer->Stop();
    }
    if (m_NetworkPtr != nullptr)
    {
        m_NetworkPtr->Exit();
    }
}

bool CServerLoader::InitSystems(void)
{
    INIT_CLASS_LOADER( CServerLoader, XUI, UUID_OF(CXUISystem), XUI_MODULE_NAME );
    INIT_CLASS_LOADER( CServerLoader, NET, UUID_OF(CNetworkSystem), NETWORK_MODULE_NAME );

    LOADER_CLASS_CREEATE( CServerLoader, XUI, UUID_OF(CXUIManager), m_UIManagerPtr.Cast<CComponent>() );
    if ((m_UIManagerPtr == nullptr) || (m_UIManagerPtr->Init() != RET_OKAY))
    {
        DEV_ERROR(TF("加载或者初始化界面模块[%s]失败!"), XUI_MODULE_NAME);
        IXWnd::MessageBoxParam(TF("加载或者初始化界面模块[%s]失败!"), TF("ServerLoader"), MB_OK, nullptr, XUI_MODULE_NAME);
        return false;
    }
    IXWnd::InitCommonCtrls((ICC_LISTVIEW_CLASSES | ICC_TAB_CLASSES | ICC_BAR_CLASSES));

    LOADER_CLASS_CREEATE( CServerLoader, NET, UUID_OF(CNetwork), m_NetworkPtr.Cast<CComponent>() );
    if (m_NetworkPtr == nullptr)
    {
        DEV_ERROR(TF("加载或者初始化网络模块[%s]失败!"), NETWORK_MODULE_NAME);
        IXWnd::MessageBoxParam(TF("加载或者初始化网络模块[%s]失败!"), TF("ServerLoader"), MB_OK, nullptr, NETWORK_MODULE_NAME);
        return false;
    }
    m_Config.m_KeyValue.AddItem(CServerConfig::NetworkPtr, (void*)&m_NetworkPtr);

    DEV_INFO(TF("初始化界面模块和网络模块完成"));
    return true;
}

void CServerLoader::ExitSystems(void)
{
    if (m_NetworkPtr != nullptr)
    {
        //m_NetworkPtr->Exit();
        m_NetworkPtr = nullptr;
        m_Config.m_KeyValue.Remove(CServerConfig::NetworkPtr);
    }
    if (m_UIManagerPtr != nullptr)
    {
        m_UIManagerPtr->Exit();
        m_UIManagerPtr = nullptr;
    }

    EXIT_CLASS_LOADER( CServerLoader, NET );
    EXIT_CLASS_LOADER( CServerLoader, XUI );
    DEV_INFO(TF("释放界面模块和网络模块完成"));
}


///////////////////////////////////////////////////////////////////////////////////////////////////////////
// _tWinMain
enum CPU_TECH_EDX
{
    // EDX
    CPUT_RDTSC  = 0x00000010, // CPU_INFO_STDTECH
    CPUT_MMX2   = 0x00400000,
    CPUT_MMX    = 0x00800000,
    CPUT_SSE    = 0x02000000, // CPU_INFO_STDTECH
    CPUT_SSE2   = 0x04000000, // CPU_INFO_STDTECH
    CPUT_HTT    = 0x10000000, // CPU_INFO_STDTECH
    CPUT_3DNOWE = 0x40000000, // CPU_INFO_EXTTECH
    CPUT_3DNOW  = 0x80000000, // CPU_INFO_EXTTECH
};

enum CPU_TECH_ECX
{
    // ECX, CPUI_STDTECH
    CPUT_SSE3   = 0x00000001,
    CPUT_SSSE3  = 0x00000200,
    CPUT_SSE41  = 0x00080000,
    CPUT_SSE42  = 0x00100000,
    CPUT_SSE4A  = 0x00000040,
};

PCXStr GetCPUVender(UInt uVender)
{
    switch (uVender)
    {
        CASE_RETSTR(CPlatform::CPUV_UNKNOWN, TF("Unknown CPU"));
        CASE_RETSTR(CPlatform::CPUV_INTEL, TF("Intel CPU"));
        CASE_RETSTR(CPlatform::CPUV_AMD, TF("AMD CPU"));
        CASE_RETSTR(CPlatform::CPUV_ARM, TF("ARM CPU"));
    default:
        {
            return TF("Unknown CPU Vender Type");
        }
    }
}

PCXStr GetOSType(UInt uOSType)
{
    switch (uOSType)
    {
        CASE_RETSTR(CPlatform::CPUV_UNKNOWN, TF("Unknown OS"));
        CASE_RETSTR(CPlatform::OST_WINDOWS, TF("Windows"));
        CASE_RETSTR(CPlatform::OST_LINUX, TF("Linux"));
        CASE_RETSTR(CPlatform::OST_MAC, TF("Mac"));
        CASE_RETSTR(CPlatform::OST_IOS, TF("iOS"));
        CASE_RETSTR(CPlatform::OST_ANDROID, TF("Android"));
    default:
        {
            return TF("Unknown OS Type");
        }
    }
}

void DumpPlatform(void)
{
    UInt uRuntime = CPlatform::GetRuntimeConfig();
    DEV_INFO(TF("---Platform Information---"));
    DEV_INFO(TF(" %s"), TF(__ARCH_TARGET_STR__));
    DEV_INFO(TF(" %s"), TF(__PLATFORM_TARGET_STR__));
    DEV_INFO(TF(" %s"), TF(__RUNTIME_CHARSET_STR__));
    DEV_INFO(TF(" %s"), (uRuntime & RUNTIME_CONFIG_DEBUG) ? TF("Debug Status") : TF("Release Status"));
    DEV_INFO(TF(" %s"), (uRuntime & RUNTIME_CONFIG_STATIC) ? TF("Static Library") : TF("Dynamic Library"));
    DEV_INFO(TF(" %s"), (uRuntime & RUNTIME_CONFIG_RTTI_HASH64) ? TF("RTTI Hash64") : TF("RTTI Hash32"));


    CPlatform::CPUINFO cpui;
    CPlatform::GetCPUInfo(cpui);
    DEV_INFO(TF("---CPU Identifier & Features---"));
    DEV_INFO(TF(" %s"), cpui.szBrand);
    DEV_INFO(TF(" Vender : %s, Cores : %d, Speed %dMHz"), GetCPUVender(cpui.usVendor), cpui.usCores, cpui.uSpeed);

    CPlatform::CPUTECH cput;
    CPlatform::GetCPUTech(cput, 1);

    DEV_INFO(TF(" Features : %s, %s, %s, %s, %s, %s, %s, %s, %s"),
             (cput.ullTech[3] & CPUT_RDTSC) ? TF("SSE2[YES]")  : TF("SSE2[NO]"),
             (cput.ullTech[3] & CPUT_MMX)   ? TF("MMX[YES]")   : TF("MMX[NO]"),
             (cput.ullTech[3] & CPUT_SSE)   ? TF("SSE[YES]")   : TF("SSE[NO]"),
             (cput.ullTech[3] & CPUT_SSE2)  ? TF("SSE2[YES]")  : TF("SSE2[NO]"),
             (cput.ullTech[3] & CPUT_HTT)   ? TF("HTT[YES]")   : TF("HTT[NO]"),
             (cput.ullTech[2] & CPUT_SSE3)  ? TF("SSE3[YES]")  : TF("SSE3[NO]"),
             (cput.ullTech[2] & CPUT_SSSE3) ? TF("SSSE3[YES]") : TF("SSSE3[NO]"),
             (cput.ullTech[2] & CPUT_SSE41) ? TF("SSE41[YES]") : TF("SSE41[NO]"),
             (cput.ullTech[2] & CPUT_SSE42) ? TF("SSE42[YES]") : TF("SSE42[NO]"));

    CPlatform::GetCPUTech(cput, 0x80000001);
    DEV_INFO(TF(" Features : %s, %s, %s, %s, %s"),
             (cput.ullTech[3] & CPUT_MMX)    ? TF("MMX[YES]")    : TF("MMX[NO]"),
             (cput.ullTech[3] & CPUT_MMX2)   ? TF("MMX2[YES]")   : TF("MMX2[NO]"),
             (cput.ullTech[3] & CPUT_3DNOW)  ? TF("3DNOW[YES]")  : TF("3DNOW[NO]"),
             (cput.ullTech[3] & CPUT_3DNOWE) ? TF("3DNOW+[YES]") : TF("3DNOW+[NO]"),
             (cput.ullTech[2] & CPUT_SSE4A)  ? TF("SSE4A[YES]")  : TF("SSE4A[NO]"));

    CPlatform::MEMINFO mem;
    CPlatform::GetMemInfo(mem);
    DEV_INFO(TF("---Memory Information---"));
    DEV_INFO(TF(" Memory Current Used       : %8d[%%]"), mem.uUsedPercent);
    DEV_INFO(TF(" Memory Page Size          : %8d[KB]"), mem.uPageSize);
    DEV_INFO(TF(" Memory Total Physical Size: %8d[MB]"), mem.uTotalPhys);
    DEV_INFO(TF(" Memory Avail Physical Size: %8d[MB]"), mem.uAvailPhys);

    CPlatform::OSINFO os;
    CPlatform::GetOSInfo(os);
    DEV_INFO(TF("---Operation System Information---"));
    DEV_INFO(TF(" OS Type        : %s"), GetOSType(os.uOSType));
    DEV_INFO(TF(" OS Version     : %d.%d Build %d"), os.uMajor, os.uMinor, os.uBuild);
    DEV_INFO(TF(" OS Description : %s"), os.szDescription);

    CPlatform::TIMEINFO time;
    CPlatform::GetTimeInfo(time);
    DEV_INFO(TF("Time : %d-%d-%d(%d), %d:%d:%d:%d"), time.usYear, time.usMonth, time.usDay, time.usWeekDay, time.usHour, time.usMinute, time.usSecond, time.usMSecond);
}

Int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, Int)
{
    CSEHExceptionFilter::Init();

    CPlatform::SetExceptHandler(&CServerLoader::ThreadExceptHandler);
    DumpPlatform();

    CoreInit();
    if (GServerLoaderInst->Init(::GetCommandLine()))
    {
        CMainFrame MainFrame;
        CXUITraits::CREATE_PARAM cpm;

        CStringFix strTemp;
        strTemp.Load(IDS_TITLE_NAME);
        cpm.pszName = *strTemp;
        if (GServerLoaderInst->m_UIManagerPtr->Create(MainFrame, cpm) != -1)
        {
            MainFrame.UpdateWindow();
            GServerLoaderInst->m_UIManagerPtr->MsgLoop();
        }
    }
    GServerLoaderInst->Exit();
    CoreExit();

    CSEHExceptionFilter::Exit();
    return 0;
}

